#include "../headers/mesh.h"

Mesh::Mesh()
{
  verts=0;
  colors=0;
  tris=0;
  uvs=0;

  nbrVerts=0;
  nbrTris=0;
  texturaID =0;
}

Mesh::~Mesh()
{
  delete [] verts;
  delete [] uvs;
  delete [] colors;
  delete [] tris;
}

void Mesh::initVerts(int p_nbrVerts)
{
  if (verts) return;
  nbrVerts=p_nbrVerts;
  verts =new Vertex[nbrVerts];
  uvs   =new     UV[nbrVerts];
  colors=new Color[nbrVerts];
  vertNorm=new Normal[nbrVerts];  
  vertNeigh=new Neighbors[nbrVerts];

}

void Mesh::initTris(int p_nbrTris)
{
  nbrTris=p_nbrTris;
  tris=new Triangle[nbrTris];
  triNorm=new Normal[nbrTris];
}
void Mesh::initNeighbors()
{
  for (int t=0;t<nbrTris;t++)
  {
    for (int v=0;v<3;v++)
    {
      vertNeigh[tris[t].vert[v]].addNeighbor(t);
    }
  }
}

void Mesh::calcNormals()
{
  // First calculate the triangle normals
  for (int t=0;t<nbrTris;t++)
  {
    calcNormal(verts[tris[t].vert[0]],
               verts[tris[t].vert[1]],
               verts[tris[t].vert[2]],
               triNorm[t]);
  }
  // Now calculate the vertex normals
  for (int v=0;v<nbrVerts;v++)
  {
    vertNorm[v].x=vertNorm[v].y=vertNorm[v].z=0;
    for (int t=0;t<vertNeigh[v].nbr;t++)
    {
      vertNorm[v].x+=triNorm[vertNeigh[v].tri[t]].x;
      vertNorm[v].y+=triNorm[vertNeigh[v].tri[t]].y;
      vertNorm[v].z+=triNorm[vertNeigh[v].tri[t]].z;
    }
    normalize(vertNorm[v]);
  }
}


void Mesh::aplicaTextura(char nometextura[30])
{
	  glEnable(GL_TEXTURE_2D);
	  glGenTextures(1,&texturaID); // Create The Texture
	  glBindTexture(GL_TEXTURE_2D,texturaID);
	  DCImage img;

	  img.load(nometextura);
	  
	  glTexImage2D(GL_TEXTURE_2D,0,3,img.width,img.width,0,GL_RGB,GL_UNSIGNED_BYTE,img.data);
	  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}

void Mesh::drawMesh2()
{	
	glBindTexture(GL_TEXTURE_2D,texturaID);
	glVertexPointer(3,GL_FLOAT,0,verts);
	glNormalPointer(GL_FLOAT,0,vertNorm);
	glTexCoordPointer(2,GL_FLOAT,0,uvs);
	glDrawElements (GL_TRIANGLES,nbrTris*3,GL_UNSIGNED_INT,tris);
}


/*
typedef struct {
  unsigned long sizeX;
  unsigned long sizeY;
  char *data;
} Image;



void Mesh::aplicaTexturaBMP()
{
	glEnable(GL_TEXTURE_2D);
	unsigned int temp;
	glGenTextures(1,&temp); // Create The Texture
	glBindTexture(GL_TEXTURE_2D,temp);
	Image img; //uses struct Image
	loadBMP( "textura.bmp", &img ); // give here the image file containing the texture
	glTexImage2D(GL_TEXTURE_2D, 0, 3, img.sizeX, img.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}


int Mesh::loadBMP( const char *filename, Image *image ){

    FILE *file;
    unsigned long size;             // size of the image in bytes.
    unsigned long i;                // standard counter.
    unsigned short int planes;      // number of planes in image (must be 1)
    unsigned short int bpp;         // number of bits per pixel (must be 24)
    char temp;                      // temporary color storage for bgr-rgb conversion.
    char k[4];

    // make sure the file is there.
    if ((file = fopen(filename, "rb"))==NULL)
    {
    printf("File Not Found : %s\n",filename);
    return 0;
    }
    
    // seek through the bmp header, up to the width/height:
    fseek(file, 18, SEEK_CUR);

    // read the width
    if ((i = fread(k, 4, 1, file)) != 1) {
    printf("Error reading width from %s.\n", filename);
    return 0;
    }

    //AND// reverse(k,4);
    image->sizeX=*(int*)k;
    
    printf("Width of %s: %lu\n", filename, image->sizeX);
    
    // read the height
    if ((i = fread(k, 4, 1, file)) != 1) {
    printf("Error reading height from %s.\n", filename);
    return 0;
    }

    //AND// reverse(k,4);
    image->sizeY=*(int*)k;

    printf("Height of %s: %lu\n", filename, image->sizeY);
    
    // calculate the size (assuming 24 bits or 3 bytes per pixel).
    size = image->sizeX * image->sizeY * 3;

    // read the planes
    if ((fread(k, 2, 1, file)) != 1) {
    printf("Error reading planes from %s.\n", filename);
    return 0;
    }
   
    reverse(k,2);
    planes=*(int*)k;
    planes=1; // :)

    if (planes != 1) {
    printf("Planes from %s is not 1: %u\n", filename, planes);
    return 0;
    }

    // read the bpp
    if ((i = fread(&bpp, 2, 1, file)) != 1) {
    printf("Error reading bpp from %s.\n", filename);
    return 0;
    }
    bpp=24;
    if (bpp != 24) {
    printf("Bpp from %s is not 24: %u\n", filename, bpp);
    return 0;
    }
    
    // seek past the rest of the bitmap header.
    fseek(file, 24, SEEK_CUR);

    // read the data.
    image->data = (char *) malloc(size);
    if (image->data == NULL) {
    printf("Error allocating memory for color-corrected image data");
    return 0;    
    }

    if ((i = fread(image->data, size, 1, file)) != 1) {
    printf("Error reading image data from %s.\n", filename);
    return 0;
    }

    for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
    temp = image->data[i];
    image->data[i] = image->data[i+2];
    image->data[i+2] = temp;
    }
    
    // we're done.
    return 1;
}


*/